package com.Sdebruijn.curriculumvitae.db;

import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import android.content.Context;

import com.Sdebruijn.curriculumvitae.models.App;
import com.Sdebruijn.curriculumvitae.models.Applicant;
import com.Sdebruijn.curriculumvitae.models.Course;
import com.Sdebruijn.curriculumvitae.models.Education;
import com.Sdebruijn.curriculumvitae.models.Experience;
import com.Sdebruijn.curriculumvitae.models.Hobby;
import com.Sdebruijn.curriculumvitae.models.Institution;
import com.Sdebruijn.curriculumvitae.models.Lesson;
import com.Sdebruijn.curriculumvitae.models.OnlinePerson;
import com.Sdebruijn.curriculumvitae.models.Person;
import com.Sdebruijn.curriculumvitae.models.Work;
import com.Sdebruijn.curriculumvitae.models.WorkTask;

/**
 * Utility class to manage access to the database via a singleton
 * 
 * @author Stefan de Bruijn
 * 
 */
public class DatabaseManager {

	/**
	 * DatabaseManager singleton instance
	 */
	private static DatabaseManager instance;

	/**
	 * Initiate the DatabaseManager singleton instance
	 * 
	 * @param ctx
	 */
	public static void init(Context ctx) {
		if (null == instance) {
			instance = new DatabaseManager(ctx);
		}
	}

	/**
	 * Entry point to receive the singleton instance, for access to the database
	 * 
	 * @return DatabaseManager instance
	 */
	public static DatabaseManager getInstance() {
		return instance;
	}

	/**
	 * DatabaseHelper object to access the Dao's
	 */
	private static DatabaseHelper helper;

	/**
	 * Private constructor. Call getInstance instead to access this object.
	 * 
	 * @param ctx
	 *            Activity's context
	 */
	private DatabaseManager(Context ctx) {
		helper = new DatabaseHelper(ctx);
	}

	/**
	 * Receive the DatabaseHelper object to access the Dao's
	 * 
	 * @return DatabaseHelper object
	 */
	public static DatabaseHelper getHelper() {
		return helper;
	}

	public static Person getApplicant() {
		List<Person> persons = null;
		Person person = null;
		try {
			persons = getHelper().getApplicantDao().queryForAll();
			person = persons.get(0);
			getHelper().getOnlinePersonDao().refresh(person.online_person);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return person;
	}

	public static List<App> getAllApps() {
		List<App> apps = null;
		try {
			apps = getHelper().getAppDao().queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return apps;
	}

	public static List<Hobby> getAllHobbies() {
		List<Hobby> hobbies = null;
		try {
			hobbies = getHelper().getHobbyDao().queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return hobbies;
	}

	public static List<Course> getAllCourses() {
		List<Course> courses = null;
		try {
			courses = getHelper().getCourseDao().queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return courses;
	}

	public static List<Experience> getAllEducation() {
		List<Experience> exp = null;
		try {
			exp = getHelper().getEducationDao().queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return exp;
	}

	public static List<Experience> getAllWork(boolean sidejobs) {
		List<Experience> exp = null;
		try {
			if (sidejobs) {
				exp = getHelper().getWorkDao().queryForAll();
			} else {
				exp = getHelper().getWorkDao().queryForEq("sidejob", false);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return exp;
	}

	public static List<Experience> getAllSideJobs() {
		List<Experience> exp = null;
		try {
			exp = getHelper().getWorkDao().queryForEq("sidejob", true);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return exp;
	}

	public static List<WorkTask> getAllWorkTask() {
		List<WorkTask> workTask = null;
		try {
			workTask = getHelper().getWorkTaskDao().queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return workTask;
	}

	public static List<Lesson> getAllLessons() {
		List<Lesson> lessons = null;
		try {
			lessons = getHelper().getLessonDao().queryForAll();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return lessons;
	}

	public static List<WorkTask> getWorkTaskByWorkId(int workId) {
		List<WorkTask> workTasks = null;
		try {
			workTasks = getHelper().getWorkTaskDao().queryForEq("work_id", workId);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return workTasks;
	}

	public static void addApplicant(Applicant applicant) {
		try {
			// Add nested child first
			addOnlinePerson(applicant.online_person);
			// Add person itself
			getHelper().getApplicantDao().createOrUpdate(applicant);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addApps(Collection<App> apps, Applicant applicant) {
		try {
			for (App app : apps) {
				app.applicant = applicant;
				getHelper().getAppDao().createOrUpdate(app);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addHobbies(Collection<Hobby> hobbies, Applicant applicant) {
		try {
			for (Hobby hobby : hobbies) {
				hobby.applicant = applicant;
				getHelper().getHobbyDao().createOrUpdate(hobby);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addCourses(Collection<Course> courses, Applicant applicant) {
		try {
			for (Course course : courses) {
				course.applicant = applicant;
				getHelper().getCourseDao().createOrUpdate(course);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addOnlinePerson(OnlinePerson onlinePerson) {
		try {
			getHelper().getOnlinePersonDao().createOrUpdate(onlinePerson);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addEducation(Collection<Education> educations) {
		try {
			for (Experience edu : educations) {
				// Add nested child first
				addInstitution(edu.institution);

				getHelper().getEducationDao().createOrUpdate(edu);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addInstitution(Institution institution) {
		try {
			getHelper().getInstitutionDao().createOrUpdate(institution);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addWork(Collection<Work> jobs) {
		try {
			for (Experience work : jobs) {
				Work w = (Work) work;
				// Add nested child first
				addInstitution(w.institution);
				addWorkTask(w.tasks, w);

				getHelper().getWorkDao().createOrUpdate(w);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public static void addWorkTask(Collection<WorkTask> worktasks, Work work) {
		if (worktasks != null && !worktasks.isEmpty()) {
			try {
				for (WorkTask wt : worktasks) {
					wt.work = work;
					getHelper().getWorkTaskDao().createOrUpdate(wt);
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

}